﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ReAnimation.Helpers.Common;
using ReAnimation.Helpers.WinForms;
using Iesi.Collections.Generic;

namespace GLWrap.SceneObjects
{
    //TODO: применение материала к группе - должно применять материал ко всем членам группы
    public class SceneObjectsGroup: SceneObject
    {
        private IList<SceneObject> _attachedObjects;
        
        public IList<SceneObject> AttachedObjects
        {
            get
            {
                return new List<SceneObject>(_attachedObjects);
            }
        }

        public override Material Material
        {
            get
            {
                return base.Material;
            }
            set
            {
                base.Material = value;
                foreach (var sceneObject in _attachedObjects)
                    sceneObject.Material = base.Material;
            }
        }


        public SceneObjectsGroup()
        {
            _attachedObjects = new List<SceneObject>();
        }

        public void AttachObject(SceneObject sceneObject)
        {
            _attachedObjects.Add(sceneObject);
            sceneObject.OnSelect += GroupObjectSelected;
            sceneObject.WillDraw += GroupObjectWillDraw;

            _sceneManagers.ForEach((sceneManager) => { sceneManager.AddSceneObject(sceneObject); });
        }

        public void AttachObjects(IEnumerable<SceneObject> sceneObjects)
        {
            sceneObjects.ForEach((sceneObject) => { AttachObject(sceneObject); });
        }

        private void GroupObjectWillDraw(object sender,EventArg<GlSceneManager> e)
        {
            GroupWillBeDrawn(e.Data);
        }

        private void GroupObjectSelected(object sender, EventArgs e)
        {
            HaveBeenSelected();
        }

        public void DetachObject(SceneObject sceneObject)
        {
            _attachedObjects.Remove(sceneObject);
            sceneObject.OnSelect -= GroupObjectSelected;
            sceneObject.WillDraw -= GroupObjectWillDraw;

            _sceneManagers.ForEach((sceneManager) => { sceneManager.RemoveSceneObject(sceneObject); });
        }

        public void DetachObjects(IEnumerable<SceneObject> sceneObjects)
        {
            sceneObjects.ForEach((sceneObject) => { DetachObject(sceneObject); });
        }

        protected sealed override void InternalDraw(GlSceneManager sceneManager)
        {
            GroupObjectWillDraw(this, new EventArg<GlSceneManager>(sceneManager));
        }

        protected sealed override void InternalAttachToScene(GlSceneManager sceneManager)
        {
            _attachedObjects.ForEach((sceneObject) => { sceneManager.AddSceneObject(sceneObject); });

            GroupAttachedToScene(sceneManager);
        }

        protected sealed override void InternalDetachFromScene(GlSceneManager sceneManager)
        {
            _attachedObjects.ForEach((sceneObject) => { sceneManager.RemoveSceneObject(sceneObject); });

            GroupDetachedFromScene(sceneManager);
        }

        protected virtual void GroupWillBeDrawn(GlSceneManager sceneManager) { }
        protected virtual void GroupAttachedToScene(GlSceneManager sceneManager) { }
        protected virtual void GroupDetachedFromScene(GlSceneManager sceneManager) { }
    }
}
